package m

import (
	"github.com/globalsign/mgo/bson"

	log "github.com/sirupsen/logrus"

	"GameServer/Game/cache"
	"GameServer/Game/dbmodule"
	"GameServer/Game/errors"
)

// 卡牌buff
type CardBuff struct {
	Tid      int64 `bson:"tid" json:"tid"`
	CardType int64 `bson:"cardType" json:"cardType"` // 卡牌类型
	UseRound int64 `bson:"useRound" json:"useRound"` // 使用回合数
	Val      int64 `bson:"val" json:"val"`           // 值
	ShowVal  int64 `bson:"showVal" json:"showVal"`   // 显示值
}

//
type Card struct {
	Id     int64 `bson:"id" json:"id"`         // 这组牌的唯一id
	Tid    int64 `bson:"tid"`                  // 卡牌tid
	Status int64 `bson:"status" json:"status"` // 卡牌状态 0-正常 1-使用 2-废弃 3-已废弃
}

// 怪物技能
type CardMonsterSkill struct {
	Tid       int64 `bson:"tid" json:"tid"`
	Cd        int64 `bson:"cd" json:"cd"`               // CD
	Val       int64 `bson:"val" json:"val"`             // 层
	ExtVal    int64 `bson:"extVal" json:"extVal"`       // 辅助数值
	ShowValue int64 `bson:"showValue" json:"showValue"` // 显示值
	SkillTyp  int64 `bson:"skillTyp" json:"skillTyp"`   // 技能类型
	StayRound int64 `bson:"stayRound" json:"stayRound"` // 保留回合
}

type HurtAttr struct {
	Tid          int64           // 卡牌tid 或者是 技能tid
	Target       int64           // 作用对象-data.CardEffectTargetEnum
	HurtType     int64           // 伤害类型枚举-data.CardHurtTypeEnum
	Typ          int64           // 伤害详细类型 1 固定伤害  2 连续伤害 3 额外伤害
	Val          int64           // 伤害数值
	ValSupport   int64           // 辅助数值
	ShieldHurt   int64           // 对护盾的伤害
	CanBloodSuck int64           // 支持吸血 1-支持
	CanFightBack int64           // 0-支持被反击  1-不支持被反击
	EffectBuff   map[int64]int64 // key-buffId value-1-受此buff影响
	ValType      int64           // 伤害数据类型 0-正常 1-闪避 2-暴击
	IsTrapVal    int64           // 是否是陷阱造成的伤害 0-普通伤害 1-陷阱伤害
	SpAtkTyp     map[int64]int64 // 伤害属性 key-属性枚举 value-1 目前无用
	Discard      int64           // 0-不是弃卡 1-弃卡效果
}

// 卡牌怪物
type CardMonster struct {
	Tid               int64                       `bson:"tid" json:"tid"`
	Hp                int64                       `bson:"hp" json:"hp"`                               // 血量
	Shield            int64                       `bson:"shield" json:"shield"`                       // 盾
	Skills            map[int64]*CardMonsterSkill `bson:"skills" json:"skills"`                       // 技能 key-Tid
	RoundHurt         int64                       `bson:"roundHurt" json:"roundHurt"`                 //当前回合受到的伤害累加
	HurtSum           int64                       `bson:"hurtSum" json:"hurtSum"`                     // 受到的伤害累加  30点 怪物发动反击时清0
	Att               int64                       `bson:"att" json:"att"`                             // 攻击伤害
	AttBrustPermanent int64                       `bson:"attBrustPermanent" json:"attBrustPermanent"` // 永久伤害增幅，百分比
	AttBrustHpPoint   int64                       `bson:"attBrustHpPoint" json:"attBrustHpPoint"`     // 精准血量增伤，百分比
}

// 卡组
type CardDeck struct {
	LockBlockTid int64           `bson:"lockBlockTid" json:"lockBlockTid"` // 该卡组记录的关卡
	ExtraCard    map[int64]int64 `bson:"extraCard" json:"extraCard"`       // 额外卡
	DeckIndex    int64           `bson:"deckIndex" json:"deckIndex"`       // 抽卡索引
	CombatDecks  []int64         `bson:"combatDecks" json:"combatDecks"`   // 战斗卡组
}

// 魔法书-
type MagicBook struct {
	Typ        int64           `bson:"typ" json:"typ"`               // 魔法书类型
	Status     int64           `bson:"status" json:"status"`         // 状态 0-没有记录 1-有记录需回滚
	GridId     int64           `bson:"gridId" json:"gridId"`         // 格子Id
	ResetCount int64           `bson:"resetCount" json:"resetCount"` // 重置次数
	CardLst    map[int64]int64 `bson:"cardLst" json:"cardLst"`       // 选择列表 key-id value-cardTid
}

// 卡牌游戏
type CardGame struct {
	BaseM
	Uid              bson.ObjectId                  `bson:"_id" json:"_id"`
	Round            int64                          `bson:"round" json:"round"` // 回合数
	Monster          *CardMonster                   `bson:"monster" json:"monster"`
	Cards            []*Card                        `bson:"cards" json:"cards"`                      // 用户手上卡牌列表
	CardBuffs        []*CardBuff                    `bson:"cardBuffs" json:"cardBuffs"`              // 卡牌buff
	Stone            int64                          `bson:"stone" json:"stone"`                      // 沸点宝石
	NextCardNumMinus int64                          `bson:"nexCardNumMinus" json:"nextCardNumMinus"` // 下一回合卡牌减少数量
	Gid              int64                          `bson:"gid" json:"gid"`                          // 当前格子id -1时，表示该怪是指定怪，不是格子挖出来的。
	Page             int64                          `bson:"page" json:"page"`                        // 第几章节
	Status           int64                          `bson:"status" json:"status"`                    // 状态 0 正常  1 胜利  2 失败 3 主动退出 4 已经领取奖励
	PlayerShield     int64                          `bson:"playerShield" json:"playerShield"`        // 玩家护盾值
	KillMonsters     map[int64]*CardGameKillMonster `bson:"killMonster" json:"killMonster"`          // 击杀怪物
	CardDeck         *CardDeck                      `bson:"cardDeck" json:"cardDeck"`                // 卡组
	MagicBook        *MagicBook                     `bson:"magicBook" json:"magicBook"`              // 魔法书记录
	LossGold         int64                          `bson:"lossGold" json:"lossGold"`                // 战斗中，玩家损失的金币
}

type CardGameKillMonster struct {
	KillNum int64 `bson:"killNum" json:"killNum"` // 击杀次数
	Round   int64 `bson:"round" json:"round"`     // 最优回合数
}

func NewCardGame() cache.EntryI {
	return &CardGame{Cards: make([]*Card, 0), CardBuffs: make([]*CardBuff, 0), Status: -1, KillMonsters: make(map[int64]*CardGameKillMonster, 0)}
}

// 保存信息
func (uCardGame *CardGame) Save() (err error) {
	mdata := make(map[string]interface{}, 0)

	mdata["_id"] = uCardGame.Uid
	mdata["monster"] = uCardGame.Monster
	mdata["cards"] = uCardGame.Cards
	mdata["cardBuffs"] = uCardGame.CardBuffs
	mdata["stone"] = uCardGame.Stone
	mdata["nexCardNumMinus"] = uCardGame.NextCardNumMinus
	mdata["gid"] = uCardGame.Gid
	mdata["page"] = uCardGame.Page
	mdata["status"] = uCardGame.Status
	mdata["playerShield"] = uCardGame.PlayerShield
	mdata["cardDeck"] = uCardGame.CardDeck
	mdata["magicBook"] = uCardGame.MagicBook

	if uCardGame.KillMonsters != nil && len(uCardGame.KillMonsters) != 0 {
		mdata["killMonster"] = uCardGame.KillMonsters
	}

	err = dbmodule.MgoDB.GameDB.Upsert("cardGame", bson.M{"_id": uCardGame.Uid}, mdata)
	if err != nil {
		return
	}
	return
}

func (uCardGame *CardGame) Load(key interface{}) (err error) {
	switch key.(type) {
	case string:
		if key.(string) == "" {
			return errors.New("无效的key load, key empty")
		}
		uCardGame.Uid = bson.ObjectIdHex(key.(string))
	case bson.ObjectId:
		uCardGame.Uid = key.(bson.ObjectId)
	default:
		log.WithFields(log.Fields{
			"method": "CardGame_Load",
			"data":   key,
		}).Error("无效的key load")
		return errors.New("无效的key load")
	}
	return uCardGame.LoadData()
}

// 加载数据
func (uCardGame *CardGame) LoadData() (err error) {
	err = dbmodule.MgoDB.GameDB.FindOne("cardGame", bson.M{"_id": uCardGame.Uid}, nil, &uCardGame)
	if err != nil {
		if err.Error() == "not found" {
			return nil
		}
		return
	}
	if uCardGame.KillMonsters == nil {
		uCardGame.KillMonsters = make(map[int64]*CardGameKillMonster, 0)
	}
	return
}

// 更新数据
func (uCardGame *CardGame) Update(val *CardGame) {
	Cache.Put("cardGame", uCardGame.Uid.Hex(), val)
	val.UpdateData()
}

// 是否是第一次击杀
func (uCardGame *CardGame) IsFirstKillMonster(tid int64) (r bool) {
	if _, ok := uCardGame.KillMonsters[tid]; ok {
		return false
	}
	return true
}

// 增加怪物击杀列表
func (uCardGame *CardGame) AddKillMonster(tid int64, round int64) {
	if round <= 0 {
		return
	}
	defer uCardGame.Update(uCardGame)
	if uCardGame.KillMonsters == nil {
		uCardGame.KillMonsters = make(map[int64]*CardGameKillMonster, 0)
		uCardGame.KillMonsters[tid] = &CardGameKillMonster{KillNum: 1, Round: round}
		return
	}
	if v, ok := uCardGame.KillMonsters[tid]; ok {
		v.KillNum += 1
		if round < v.Round {
			v.Round = round
		}
		return
	}
	uCardGame.KillMonsters[tid] = &CardGameKillMonster{KillNum: 1, Round: round}
}

func (u *User) GetCardGame() (r *CardGame) {
	v, _ := Cache.Get("cardGame", u.Uid.Hex())
	r = v.(*CardGame)
	return
}

// 获取用户卡组
func (uCardGame *CardGame) GetCardDeck(LockBlockTid int64) (cardDeck *CardDeck) {
	needUpdate := false
	if uCardGame.CardDeck == nil {
		uCardGame.CardDeck = &CardDeck{
			LockBlockTid: LockBlockTid,
			ExtraCard:    make(map[int64]int64, 0),
			DeckIndex:    0,
			CombatDecks:  make([]int64, 0),
		}
		needUpdate = true
	}
	if uCardGame.CardDeck.LockBlockTid != LockBlockTid {
		uCardGame.CardDeck = &CardDeck{
			LockBlockTid: LockBlockTid,
			ExtraCard:    make(map[int64]int64, 0),
			DeckIndex:    0,
			CombatDecks:  make([]int64, 0),
		}
		needUpdate = true
	}
	if uCardGame.CardDeck.ExtraCard == nil {
		uCardGame.CardDeck.ExtraCard = make(map[int64]int64, 0)
		needUpdate = true
	}
	if needUpdate {
		uCardGame.Update(uCardGame)
	}
	return uCardGame.CardDeck
}

// 获取用户魔法书记录
func (uCardGame *CardGame) GetMagicBookInfo() (magicBook *MagicBook) {
	needUpdate := false
	if uCardGame.MagicBook == nil {
		uCardGame.MagicBook = &MagicBook{
			Typ:        0, // 魔法书类型
			Status:     0, // 0-没有记录 1-有记录需回滚
			ResetCount: 0, // 重置次数
			CardLst:    make(map[int64]int64, 0),
		}
		needUpdate = true
	}
	if uCardGame.MagicBook.CardLst == nil {
		uCardGame.MagicBook.CardLst = make(map[int64]int64, 0)
		needUpdate = true
	}
	if needUpdate {
		uCardGame.Update(uCardGame)
	}
	return uCardGame.MagicBook
}
